﻿using System;
using System.ServiceModel;
using System.Transactions;
using VideoServices.Business.Facade;
using VideoServices.Common.Enum;
using VideoServices.Domain.Entities;
using VideoServices.Services.Dto;
using VideoServices.Services.Interface;
using VideoServices.Services.Response;
using VideoServices.Services.Translation;
using VideoServices.Services.Translation.Base;
using VideoServices.Services.Translation.Factory;

namespace VideoServices.Services
{
    public class DeliveryService : IDeliveryService
    {
        #region Implementation of IDeliveryService

        /// <summary>
        /// Creates the delivery.
        /// </summary>
        /// <param name="newDeliveryDto">The new delivery dto.</param>
        /// <param name="reportDeliveryStatusTo">The report delivery status to.</param>
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void CreateDelivery(DeliveryDto newDeliveryDto, string reportDeliveryStatusTo)
        {
            DeliveryStatusServiceClient statusProxy;
            NetMsmqBinding msmqCallbackBinding;
            TransactionScope scope = null;
            try
            {
                scope = new TransactionScope(TransactionScopeOption.Required);
                var facade = VideoServicesFacade.Instance;
                ITranslator translator = TranslatorFactory.GetTranslatorByType(typeof(DeliveryTranslator));
                var deliveryEntity = translator.TranslateToEntity<DeliveryDto, Delivery>(newDeliveryDto);
                Delivery savedEntity = facade.CreateDelivery(deliveryEntity);
                DeliveryDto deliveryDto = translator.TranslateToDto<Delivery, DeliveryDto>(savedEntity);
                msmqCallbackBinding = new NetMsmqBinding("TransactedBinding");
                statusProxy = new DeliveryStatusServiceClient(msmqCallbackBinding,
                                                              new EndpointAddress(reportDeliveryStatusTo));
                statusProxy.PublishDeliveryStatus(deliveryDto.Id, deliveryDto.Status);
                scope.Complete();

            }
            catch (Exception ex)
            {
                if (scope == null)
                {
                    scope = new TransactionScope(TransactionScopeOption.Required);
                }
                msmqCallbackBinding = new NetMsmqBinding("TransactedBinding");
                statusProxy = new DeliveryStatusServiceClient(msmqCallbackBinding,
                                                              new EndpointAddress(reportDeliveryStatusTo));
                statusProxy.PublishDeliveryStatus(newDeliveryDto.Id, DeliveryStatus.Cancelled);
                scope.Complete();
            }
            finally
            {
                if (scope != null) scope.Dispose();
            }
        }

        /// <summary>
        /// Gets the delivery by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Response<DeliveryDto> GetDeliveryById(int id)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}